#include "manipulatorbase.h"
#include "actorbase.h"
#include "effectcontainermanager.h"
#include "layersmanager.h"
#include "environmentlayeractor.h"
#include <osgViewer\Viewer>
#include "utility.h"

namespace ControlCenter
{
	ManipulatorBase::ManipulatorBase():_lostFocus(false),_usePickManager(true)
		,_boolFocusInGraphWin(true),_viewType(VIEW_TYPE_EDITER),_maxradius(FLT_MAX)
		,_environmentLayer(NULL),_view(NULL)
	{
		_operatorObjectVector.clear();
		_operateObjType = GET_TYPE_INT_FROM_STRING(CLASS_DEVICE);
	}

	ManipulatorBase::~ManipulatorBase()
	{}

	void ManipulatorBase::setOperatorObjectVector(QVector<CoreBase::ActorBase*> objvector)
	{
		_operatorObjectVector.clear();
		_operatorObjectVector = objvector;
	}

	void ManipulatorBase::addOperatorObject(CoreBase::ActorBase* obj)
	{
		_operatorObjectVector.push_back(obj);
	}

	QVector<CoreBase::ActorBase*>	ManipulatorBase::getOperatorObjectVector()
	{
		return _operatorObjectVector;
	}

	void ManipulatorBase::setLookAt(const osg::Vec3& eye,const osg::Vec3& center,const osg::Vec3& up,float distance,bool rightaway)
	{}

	void ManipulatorBase::getLookAt(osg::Vec3& eye,osg::Vec3& center,osg::Vec3& up,float& distance)
	{}

	void ManipulatorBase::useCollisionCamera(bool use)
	{
		_useCollisionCamera = use;
	}

	void ManipulatorBase::flushMouseEventStack()
	{
		_ga_t1 = NULL;
		_ga_t0 = NULL;
	}

	void ManipulatorBase::flushKeyEventStack()
	{
		_key_t1 = NULL;
		_key_t0 = NULL;
	}

	void ManipulatorBase::addMouseEvent(const osgGA::GUIEventAdapter& ea)
	{
		_ga_t1 = _ga_t0;
		_ga_t0 = &ea;
	}

	void ManipulatorBase::addKeyEvent(const osgGA::GUIEventAdapter& ea)
	{
		_key_t1 = _key_t0;
		_key_t0 = &ea;
	}

	bool ManipulatorBase::graphWindowHaveFocus(const int x,const int y)
	{
		bool wmhave = VrDataCore::EffectContainerManager::GetInstance().hudWindowManagerHaveFocus(x,y);
		return !wmhave;
	}

	void ManipulatorBase::initManipulatorStart(const osg::Vec3& eye,const osg::Vec3& center,const osg::Vec3& up)
	{
		_homeEye = eye;
		_homeCenter = center;
		_homeUp = up;
	}

	void ManipulatorBase::setToolAction(ActionData* action)
	{
		_action = action->_actionKey;
	}

	bool ManipulatorBase::testInSky(const osg::Matrixd& before,const osg::Matrixd& after,osg::Vec3& intersectz,bool& movein)
	{
		if(_environmentLayer == NULL)
		{
			_environmentLayer = dynamic_cast<VrDataCore::EnvironmentLayerActor*>(VrDataCore::LayersManager::GetInstance().getEnvironmentLayer());
			bool enable;
			QString type,active;
			_environmentLayer->getSkyDomeEnable(enable,type,active,_maxradius);
			_maxradius = _maxradius*0.5f;
		}
		osg::Vec3 skypos = _environmentLayer->getSkyOffset();
		if((after.getTrans() - skypos).length()>_maxradius)
		{
			double x[2], y[2], z[2] = {-1,-1};
			intersectionTestSphereWithSegment(after.getTrans().x(),after.getTrans().y(),after.getTrans().z(),
				skypos.x(),skypos.y(),skypos.z(),skypos.x(),skypos.y(),skypos.z(),_maxradius,x,y,z);
			for(int i=0;i<2;++i)
			{
				if(z[i]>0)
				{
					intersectz = osg::Vec3(x[i],y[i],z[i]);
				}
			}
			if((after.getTrans() - skypos).length()>(before.getTrans() - skypos).length())
				movein = false;
			else
				movein = true;
			return false;
		}
		else
			return true;
	}
}